#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "UsePins.h"
#include "DHT11.h"

void DHT11_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(DHT11_APB, ENABLE);

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
    GPIO_InitStructure.GPIO_Pin = DHT11_Pin;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(DHT11_GPIO, &GPIO_InitStructure);

    GPIO_SetBits(DHT11_GPIO, DHT11_Pin);
}

void DHT11_W_Pin(uint8_t BitValue)
{
    GPIO_WriteBit(DHT11_GPIO, DHT11_Pin, (BitAction)BitValue);
}

uint8_t DHT11_R_Pin(void)
{
    return GPIO_ReadInputDataBit(DHT11_GPIO, DHT11_Pin);
}

void DHT11_Start(void)
{
    DHT11_W_Pin(0);
    Delay_ms(30);
    DHT11_W_Pin(1);
    Delay_us(13);
}

uint8_t DHT11_Check(void)
{
    uint8_t rety = 0;

    rety = 0;
    while (DHT11_R_Pin() == 0 && rety < 100)
    {
        rety++;
        Delay_us(1);
    }
    if (rety >= 100)
    {
        return 0;
    }
    while (DHT11_R_Pin() == 1 && rety < 100)
    {
        rety++;
        Delay_us(1);
    }
    if (rety >= 100)
    {
        return 0;
    }
    return 1;
}

uint8_t DHT11_Byte(void)
{
    uint8_t Recbyte = 0x00, i = 0;
    for (i = 0; i < 8; i++)
    {
        while (DHT11_R_Pin() == 1)
            ;
        while (DHT11_R_Pin() == 0)
            ; //  ȴ   ʼ źŽ   
        Delay_us(40);
        if (DHT11_R_Pin() == 1)
        {
            Recbyte |= (0x80 >> i);
        }
    }
    return Recbyte;
}

void DHT11_End(void)
{
    Delay_us(60);
}

uint8_t Read_DHT11(uint8_t *Recbyte)
{
    uint8_t Tem_H = 0, Tem_L = 0, Hum_H = 0, Hum_L = 0, Check_Byte = 0;
    DHT11_Start();
    if (DHT11_Check() == 1)
    {
        Hum_H = DHT11_Byte();
        Hum_L = DHT11_Byte();
        Tem_H = DHT11_Byte();
        Tem_L = DHT11_Byte();
        Check_Byte = DHT11_Byte();
        DHT11_End();
    }
    else
    {
        return 0;
    }
    if ((Hum_H + Hum_L + Tem_H + Tem_L) != Check_Byte)
    {
        return 0;
    }
    else
    {
        Recbyte[0] = Hum_H;
        Recbyte[1] = Hum_L;
        Recbyte[2] = Tem_H;
        Recbyte[3] = Tem_L;
        return 1;
    }
}

